package com.hex.ds.em.hcdp.gauss.analyze.script.performance;

import static com.hex.ds.em.hcdp.gauss.pack.service.impl.ScriptPackTaskServiceImpl.wordResult;

import cn.hutool.core.util.StrUtil;
import com.hex.ds.em.hcdp.basic.common.IResultForReport;
import com.hex.ds.em.hcdp.gauss.analyze.script.performance.entity.CheckLeftJoinEntity;
import com.hex.ds.em.hcdp.gauss.analyze.script.performance.entity.CheckOrIndexEntity;
import com.hex.ds.em.hcdp.gauss.analyze.script.performance.entity.CheckOrLogicOperatorEntity;
import com.hex.ds.em.hcdp.gauss.common.entity.ScriptPackScanResultEntity;
import com.hex.ds.em.hcdp.gauss.common.enums.AntlrEnum;
import com.hex.hdtp.common.utils.AntlrUtil;
import com.hex.hlrt.gauss.g4.basic.gen.GaussParser;
import com.hex.hlrt.gauss.g4.basic.gen.GaussParser.ExpressionContext;
import com.hex.hlrt.gauss.g4.basic.gen.GaussParser.Logical_expressionContext;
import com.hex.hlrt.gauss.g4.basic.gen.GaussParser.Relational_expressionContext;
import com.hex.hlrt.gauss.g4.basic.gen.GaussParser.Where_clauseContext;
import com.hex.hlrt.gauss.g4.basic.gen.GaussParserBaseListener;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.antlr.v4.runtime.tree.ParseTree;
import org.apache.poi.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

/**
 * @Package com.hex.ds.em.hcdp.gauss.analyze.script.performance
 * @ClassName CheckOrIndexListener
 * @Description 检查or在where条件下是否涉及索引, 如果涉及可以分成两个语句进行处理
 * @Author gj.xu
 * @Date 2024/9/23 13:43
 * @Version v2.0
 **/
@Slf4j
@Accessors(chain = true)
@Scope(value = "prototype")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@Service("Gauss-CheckOrIndex")
public class CheckOrIndexListener extends GaussParserBaseListener implements IResultForReport {

  @Override
  public void exitWhere_clause(Where_clauseContext ctx) {
    if (ctx.expression() != null && ctx.expression().logical_expression() != null
        && ctx.expression().logical_expression().OR() != null) {
      List<Logical_expressionContext> logical_expressionContexts = ctx.expression()
          .logical_expression().logical_expression();
      //获取OR前表达式的列
      Relational_expressionContext relational_expressionContext1 = (Relational_expressionContext) AntlrUtil
          .queryDesignateChildrenOfSumObj(logical_expressionContexts.get(0),
              Relational_expressionContext.class).get(0);
      String orLeftColumn = "";
      Boolean isLeftComplex = false;
      if (relational_expressionContext1.relational_expression().size() == 2) {
        orLeftColumn = relational_expressionContext1.relational_expression(0).getText()
            .trim();
      } else if (relational_expressionContext1.compound_expression() != null) {
        if (relational_expressionContext1.compound_expression().in_elements() != null
            || relational_expressionContext1.compound_expression().between_elements() != null
            || relational_expressionContext1.compound_expression().concatenation().size() > 1) {
          orLeftColumn = relational_expressionContext1.compound_expression().concatenation(0)
              .getText().trim();
        } else {
          //复杂结构的
          isLeftComplex = true;
          orLeftColumn = relational_expressionContext1.compound_expression().concatenation(0)
              .getText().trim();
        }
      }

      //获取OR后表达式的列
      Relational_expressionContext relational_expressionContext2 = (Relational_expressionContext) AntlrUtil
          .queryDesignateChildrenOfSumObj(logical_expressionContexts.get(1),
              Relational_expressionContext.class).get(0);
      String orRightColumn = "";
      Boolean isRightComplex = false;
      if (relational_expressionContext2.relational_expression().size() == 2) {
        orRightColumn = relational_expressionContext2.relational_expression(0).getText()
            .trim();
      } else if (relational_expressionContext2.compound_expression() != null) {
        if (relational_expressionContext2.compound_expression().in_elements() != null
            || relational_expressionContext2.compound_expression().between_elements() != null
            || relational_expressionContext2.compound_expression().concatenation().size() > 1) {
          orRightColumn = relational_expressionContext2.compound_expression().concatenation(0)
              .getText().trim();
        } else {
          //复杂结构的
          isRightComplex = true;
          orRightColumn = relational_expressionContext2.compound_expression().concatenation(0)
              .getText().trim();
        }
      }

      //判断列是否是索引
      if (isColumnIndexed(orLeftColumn, isLeftComplex) && isColumnIndexed(orRightColumn,
          isRightComplex) && !orLeftColumn.equalsIgnoreCase(orRightColumn)) {
        // 更新扫描后word指标结果
        setResultForWordReport();

        CheckOrIndexEntity ruleEntity = new CheckOrIndexEntity();
        ctx.expression().logical_expression().addHeadAnyChild(ruleEntity);
        log.info("rule-[CheckOrIndex]:");
      }
    }
  }

  /**
   * @Method isColumnIndexed <br>
   * @Param columnName<br>
   * @Return java.lang.Boolean <br>
   * @Description 判断列是否是索引<br>
   * @Author sf.zheng<br>
   * @Date 2024/9/23 14:23 <br>
   * @Version V1.0<br>
   */
  private Boolean isColumnIndexed(String columnName, Boolean isComplex) {
    if (!isComplex && StrUtil.endWithIgnoreCase(columnName, "_idx")) {
      return true;
    }
    if (isComplex && StrUtil.containsIgnoreCase(columnName, "_idx")) {
      return true;
    }
    return false;
  }

  @Override
  public void setResultForWordReport() {
    ScriptPackScanResultEntity result = wordResult.get(AntlrEnum.OR_INDEX_CHECK.getValue());
    if (result == null) {
      return;
    }
    result.setScanTable("").setScanState("fail");
    wordResult.put(AntlrEnum.OR_INDEX_CHECK.getValue(), result);
  }
}